﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Test.Properties;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace Test
{
    public enum CardStats
    {
        Selected,
        Out,
        Normal,
    }
    public enum CardOrientation
    {
        Left,
        Right,
        Top,
        Botton,
    }
    public enum CardType
    {
        H = 3,
        F = 0,
        C = 2,
        B = 1,
        J = 4,
    }
    public enum CardEnum
    {
        Card_A = 1,
        Card_2 = 2,
        Card_3 = 3,
        Card_4 = 4,
        Card_5 = 5,
        Card_6 = 6,
        Card_7 = 7,
        Card_8 = 8,
        Card_9 = 9,
        Card_10 = 10,
        Card_J = 11,
        Card_Q = 12,
        Card_K = 13,
    }
    public class Card
    {
        bool _Visible = false;
        public bool Visible
        {
            get { return _Visible; }
            set { _Visible = value; }
        }
        CardType _Type;
        public CardType Type { get { return _Type; } }
        CardEnum _CardNum;
        public CardEnum CardNum { get { return _CardNum; } }
        int _Value = -1;
        public int Value { get { return _Value; } }
        Image _CardImg = null;
        public Image CardImg
        {
            get
            {
                if (_CardImg == null)
                {
                    if (_Visible)
                        _CardImg = (Image)Resources.ResourceManager.GetObject(string.Format("_{0}{1:00}", (int)_Type, (int)_CardNum));
                    else
                        _CardImg = (Image)Resources.ResourceManager.GetObject("back");
                }
                return _CardImg;
            }
        }
        PointF _Location = new PointF(0, 0);
        public PointF Location { get { return _Location; } set { _Location = value; } }
        CardOrientation _Ori = CardOrientation.Top;
        public CardOrientation Orientation
        {
            get { return _Ori; }
            set { _Ori = value; }
        }
        public Card(CardType pType, CardEnum pCardNum, int pValue,bool pVisible)
        {
            _Type = pType;
            _CardNum = pCardNum;
            _Visible = pVisible;
        }
        public string ToString()
        {
            string tmpStr = "";
            switch (_Type)
            {
                case CardType.H:
                    tmpStr = "红桃";
                    break;
                case CardType.F:
                    tmpStr = "草花";
                    break;
                case CardType.C:
                    tmpStr = "方块";
                    break;
                case CardType.B:
                    tmpStr = "黑桃";
                    break;
                case CardType.J:
                    tmpStr = "怪物";
                    break;
                default:
                    break;
            }
            switch (_CardNum)
            {
                case CardEnum.Card_A:
                    tmpStr += "A";
                    break;
                case CardEnum.Card_2:
                case CardEnum.Card_3:
                case CardEnum.Card_4:
                case CardEnum.Card_5:
                case CardEnum.Card_6:
                case CardEnum.Card_7:
                case CardEnum.Card_8:
                case CardEnum.Card_9:
                case CardEnum.Card_10:
                    tmpStr += Convert.ToString((int)_CardNum);
                    break;
                case CardEnum.Card_J:
                    tmpStr += "J";
                    break;
                case CardEnum.Card_Q:
                    tmpStr += "Q";
                    break;
                case CardEnum.Card_K:
                    tmpStr += "K";
                    break;
                default:
                    break;
            }
            return tmpStr;
        }
        Control _OwnerCtrl = null;
        public Control OwnerCtrl
        {
            get { return _OwnerCtrl; }
            set { _OwnerCtrl = value; }
        }
        CardStats _Stats = CardStats.Normal;
        public CardStats Stats
        {
            get
            {
                return _Stats;
            }
            set
            {
                _Stats = value;
            }
        }
    }
    class CardBase
    {
        Dictionary<int, Card> mCards = new Dictionary<int, Card>();
        List<int> mCurrentCardIdx = new List<int>();
        int mActiveCards;
        public CardBase(int pActiveNums, string[] pExpCards)
        {
            mActiveCards = pActiveNums;
        }
        public void Init()
        {
            foreach (Card tmpCard in mCards.Values)
            {
                if (tmpCard.OwnerCtrl != null)
                {
                    tmpCard.OwnerCtrl.Parent.Controls.Remove(tmpCard.OwnerCtrl);
                    tmpCard.OwnerCtrl.Dispose();
                }
            }
            mCards.Clear();
            mCurrentCardIdx.Clear();
            Random tmpRnd = new Random(System.Environment.TickCount);
            int tmpCurCard = -1, tmpTypeIdx = -1, tmpCardIdx = -1;
            for (int i = 0; i < mActiveCards * 4; i++)
            {

                while (tmpCurCard == -1 || mCurrentCardIdx.Contains(tmpCurCard))
                {
                    tmpTypeIdx = tmpRnd.Next(0, 4);
                    tmpCardIdx = tmpRnd.Next(1, mActiveCards + 1);
                    if (tmpCardIdx > 13)
                        tmpCardIdx = tmpCardIdx % 13;
                    tmpCurCard = tmpTypeIdx * 100 + tmpCardIdx;
                }
                mCurrentCardIdx.Add(tmpCurCard);
            }
        }
        //30,60,90
        public Card CutCards(int pPos)
        {
            Init();
            int tmpTypeIdx = -1, tmpCardIdx = -1,tmpCurCard = 999, tmpL = -1, tmpU = -1;
            Card tmpCard = null;
            while (tmpCurCard > mCurrentCardIdx.Count)
            {
                Random tmpRnd = new Random(Environment.TickCount);
                tmpL = tmpRnd.Next(pPos - 10, pPos);
                tmpL = Convert.ToInt32((float)mActiveCards * 4 * ((float)tmpL / 100f));
                tmpU = tmpRnd.Next(pPos, pPos + 10);
                tmpU = Convert.ToInt32((float)mActiveCards * 4 * ((float)tmpU / 100f));
                tmpCurCard = tmpRnd.Next(tmpL, tmpU);
            }
            tmpCurCard = mCurrentCardIdx[tmpCurCard];
            tmpTypeIdx = Convert.ToInt32(tmpCurCard / 100);
            tmpCardIdx =Convert.ToInt32((((float)tmpCurCard / 100f - (float)tmpTypeIdx) * 100));
            tmpCard = new Card((CardType)tmpTypeIdx, (CardEnum)tmpCardIdx, -1, true);
            Init();
            return tmpCard;
        }
        public Card GetCard(bool pGuest)
        {
            int tmpTypeIdx = -1, tmpCardIdx = -1, tmpCurCard = -1;
            while (tmpCardIdx==-1 || mCards.ContainsKey(tmpCardIdx))
            {
                tmpCardIdx = (new Random(System.Environment.TickCount)).Next(mCurrentCardIdx.Count - 1);
                tmpCardIdx = mCurrentCardIdx[tmpCardIdx];
            }
            tmpCurCard = tmpCardIdx;
            tmpTypeIdx = Convert.ToInt32(tmpCurCard / 100);
            tmpCardIdx =Convert.ToInt32((((float)tmpCurCard / 100f - (float)tmpTypeIdx) * 100));
            Card tmpCard = new Card((CardType)tmpTypeIdx, (CardEnum)tmpCardIdx, -1, pGuest);
           

            mCards.Add(tmpCurCard, tmpCard);
            if (tmpTypeIdx != -1 && tmpCardIdx != -1)
                return tmpCard;
            else
                return null;
        }
        public void Dispense(int pCardNum, Control pParent, CardOrientation pCardOri, bool pGuest)
        {
            CardBase tmpCardMang = this;
            PictureBox tmpPBox;
            int x = 0;
            var t = from c in mCards.Values
                    where c.OwnerCtrl != null && c.OwnerCtrl.Equals(pParent)
                    select c;
            foreach (Card tmpC in t)
            {
                tmpC.OwnerCtrl.Dispose();
                pParent.Controls.Remove(tmpC.OwnerCtrl);
            }
            Card tmpCard = null;
            for (int i = 0; i < pCardNum; i++)
            {
                tmpCard = null;
                while (tmpCard == null || tmpCard.CardImg == null)
                    tmpCard = tmpCardMang.GetCard(!pGuest);
                tmpCard.Orientation = pCardOri;
                tmpPBox = new PictureBox();
                tmpPBox.Name = string.Format("__CardPic_{0}", tmpCard.ToString());
                tmpPBox.Parent = pParent;
                tmpPBox.Image = tmpCard.CardImg;
                Image tmpImg = null;
                if (pCardOri == CardOrientation.Top || pCardOri == CardOrientation.Botton)
                    tmpImg = Image.FromHbitmap((new Bitmap(tmpCard.CardImg.Width, tmpCard.CardImg.Height, PixelFormat.Format32bppArgb)).GetHbitmap());
                else
                    tmpImg = Image.FromHbitmap((new Bitmap(tmpCard.CardImg.Height, tmpCard.CardImg.Width, PixelFormat.Format32bppArgb)).GetHbitmap());
                Graphics g = Graphics.FromImage(tmpImg);
                Matrix tmpM = new Matrix();
                int tmpRoate = 0;
                switch (pCardOri)
                {
                    case CardOrientation.Left:
                    case CardOrientation.Right:
                        tmpRoate = 90;
                        break;
                    case CardOrientation.Top:
                    case CardOrientation.Botton:
                        tmpRoate = 0;
                        break;
                }
                tmpM.RotateAt(tmpRoate, new PointF(tmpImg.Width / 2, tmpImg.Height / 2));
                g.Transform = tmpM;
                g.Clear(Color.Transparent);
                if (pCardOri == CardOrientation.Top || pCardOri == CardOrientation.Botton)
                    g.DrawImage(tmpCard.CardImg, new Point(0, 0));
                else
                    g.DrawImage(tmpCard.CardImg, new PointF(13f, -12.1f));
                tmpM.Dispose();
                g.Dispose();
                tmpPBox.Image = tmpImg;
                tmpPBox.Visible = true;
                x += 15;
                switch (pCardOri)
                {
                    case CardOrientation.Left:
                        tmpPBox.Location = new Point(15, x);
                        tmpPBox.BringToFront();
                        break;
                    case CardOrientation.Right:
                        tmpPBox.Location = new Point(pParent.ClientRectangle.Width - tmpImg.Width - 15, x);
                        tmpPBox.SendToBack();
                        break;
                    case CardOrientation.Top:
                        tmpPBox.Location = new Point(x, pParent.ClientRectangle.Height - tmpImg.Height - 15);
                        tmpPBox.SendToBack();
                        break;
                    case CardOrientation.Botton:
                        tmpPBox.Location = new Point(x, 15);
                        tmpPBox.BringToFront();
                        break;
                }
                tmpPBox.SizeMode = PictureBoxSizeMode.AutoSize;
                tmpPBox.Tag = tmpCard;
                tmpCard.OwnerCtrl = tmpPBox;
                tmpPBox.MouseEnter += new EventHandler(CardPicBox_MouseEnter);
                tmpPBox.MouseLeave += new EventHandler(CardPicBox_MouseLeave);
                tmpPBox.MouseDown += new MouseEventHandler(CardPicBox_MouseDown);

            }
        }
        void CardPicBox_MouseDown(object sender, MouseEventArgs e)
        {
            PictureBox tmpCardPic = (sender as PictureBox);
            Card tmpCard = (Card)tmpCardPic.Tag;
            if (tmpCard.Stats == CardStats.Selected)
                tmpCard.Stats = CardStats.Normal;
            else
                tmpCard.Stats = CardStats.Selected;
        }
        void CardPicBox_MouseLeave(object sender, EventArgs e)
        {
            PictureBox tmpCardPic = (sender as PictureBox);
            Card tmpCard = (Card)tmpCardPic.Tag;
            if (tmpCard.Stats == CardStats.Normal)
                switch (tmpCard.Orientation)
                {
                    case CardOrientation.Left:
                        tmpCardPic.Location = new Point(15, tmpCardPic.Location.Y);
                        break;
                    case CardOrientation.Right:
                        tmpCardPic.Location = new Point(tmpCardPic.Location.X + 15, tmpCardPic.Location.Y);
                        break;
                    case CardOrientation.Top:
                        tmpCardPic.Location = new Point(tmpCardPic.Location.X, tmpCardPic.Location.Y- 15);
                        break;
                    case CardOrientation.Botton:
                        tmpCardPic.Location = new Point(tmpCardPic.Location.X, 15);
                        break;
                }

        }
        void CardPicBox_MouseEnter(object sender, EventArgs e)
        {
            PictureBox tmpCardPic = (sender as PictureBox);
            Card tmpCard = (Card)tmpCardPic.Tag;
            if (tmpCard.Stats == CardStats.Normal)
                switch (tmpCard.Orientation)
                {
                    case CardOrientation.Left:
                        tmpCardPic.Location = new Point(tmpCardPic.Location.X + 15, tmpCardPic.Location.Y);
                        break;
                    case CardOrientation.Right:
                        tmpCardPic.Location = new Point(tmpCardPic.Location.X - 15, tmpCardPic.Location.Y);
                        break;
                    case CardOrientation.Top:
                        tmpCardPic.Location = new Point(tmpCardPic.Location.X, tmpCardPic.Location.Y + 15);
                        break;
                    case CardOrientation.Botton:
                        tmpCardPic.Location = new Point(tmpCardPic.Location.X, tmpCardPic.Location.Y - 15);
                        break;

                }

        }
    }
}